package cn.funeralobjects.ams.service.impl;

import cn.funeralobjects.ams.entity.EProduct;
import cn.funeralobjects.ams.entity.EProductApi;
import cn.funeralobjects.ams.model.ProductApi;
import cn.funeralobjects.ams.repository.BaseAmsRepository;
import cn.funeralobjects.ams.repository.EProductApiAccessRepository;
import cn.funeralobjects.ams.repository.EProductApiRepository;
import cn.funeralobjects.ams.service.AccessKeyService;
import cn.funeralobjects.ams.service.ProductApiService;
import cn.funeralobjects.common.jpa.service.JpaNameService;
import cn.funeralobjects.common.repository.NameRepository;
import cn.funeralobjects.common.service.annotataion.CommonService;
import cn.funeralobjects.common.service.exception.DataConflictException;
import cn.funeralobjects.common.service.validate.DataCheck;
import cn.funeralobjects.util.Assert;
import cn.funeralobjects.util.NumberUtils;
import cn.funeralobjects.util.annotation.ArgHasLength;
import cn.funeralobjects.util.annotation.ArgNotZero;
import cn.funeralobjects.util.annotation.AssertArg;
import com.querydsl.jpa.JPQLQueryFactory;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author FuneralObjects
 * Create date: 2020/5/28 5:03 PM
 */
@CommonService
public class ProductApiServiceImpl implements ProductApiService, BaseJpaAmsService<ProductApi, EProductApi, Integer>, JpaNameService<EProductApi, Integer> {

    @Resource
    private EProductApiRepository eProductApiRepository;

    @Resource
    private EProductApiAccessRepository eProductApiAccessRepository;

    @Resource
    private AccessKeyService accessKeyService;

    @Resource
    private JPQLQueryFactory jpqlQueryFactory;

    @Override
    public BaseAmsRepository<EProductApi, Integer> baseAmsRepository() {
        return eProductApiRepository;
    }

    @AssertArg
    @Override
    public void checkConflict(@AssertArg ProductApi productApi) throws DataConflictException {
        DataCheck.conflictData(this.existsApi(productApi.getProductId(), productApi.getAction(), productApi.getVersion()),
                () -> createDataCode("productId-action-name", productApi.getProductId() + "-" + productApi.getAction() + "-" + productApi.getVersion()));
    }

    @Override
    public EProductApi toEntity(ProductApi productApi) {
        return productApi == null ? null : new EProductApi()
                .setVersion(productApi.getVersion())
                .setAction(productApi.getAction())
                .setName(productApi.getName())
                .setProtocol(productApi.getProtocol())
                .setDomain(productApi.getDomain())
                .setMethod(productApi.getMethod())
                .setProduct(productApi.getProductId() == null ? null : new EProduct().setId(productApi.getProductId()));
    }

    @Override
    public NameRepository<EProductApi, Integer> nameRepository() {
        return eProductApiRepository;
    }

    @AssertArg
    @Override
    public void checkConflict(@AssertArg ProductApi productApi, @ArgNotZero Integer withoutId) throws DataConflictException {
        DataCheck.conflictData(this.existsApi(productApi.getProductId(), productApi.getAction(), productApi.getVersion(), withoutId),
                () -> createDataCode("productId-action-name", productApi.getProductId() + "-" + productApi.getAction() + "-" + productApi.getVersion()));
    }

    @Override
    public void copyToEntity(ProductApi sourceModify, EProductApi targetEntity) {
        targetEntity.setAction(sourceModify.getAction())
                .setMethod(targetEntity.getMethod())
                .setName(targetEntity.getName())
                .setProtocol(targetEntity.getProtocol())
                .setDomain(targetEntity.getDomain())
                .setVersion(targetEntity.getVersion())
                .setProduct(sourceModify.getProductId() == null ? null : new EProduct().setId(targetEntity.getId()));
    }

    @Override
    public boolean isValid(Integer id) {
        return NumberUtils.notZero(id);
    }

    @Override
    public void validateModify(ProductApi productApi) {
        Assert.argAssert(productApi, "productApi");
    }

    @AssertArg
    @Override
    public boolean existsApi(@ArgNotZero Integer productId, @ArgHasLength String action, @ArgHasLength String version) {
        return eProductApiRepository.existsAllByProduct_IdAndActionAndVersion(productId, action, version);
    }

    @Override
    public boolean existsApi(@ArgNotZero Integer productId, @ArgHasLength String action, @ArgHasLength String version, @ArgNotZero Integer withoutId) {
        return eProductApiRepository.existsAllByProduct_IdAndActionAndVersionAndIdNot(productId, action, version, withoutId);
    }

    @AssertArg
    @Override
    public Optional<EProductApi> findOne(@ArgNotZero Integer productId, @ArgHasLength String action, @ArgHasLength String version) {
        return eProductApiRepository.findFirstByProduct_IdAndActionAndVersion(productId, action, version);
    }

}
